package edu.cmsc611.textsimulator;

import java.util.Comparator;
import java.util.LinkedList;
import java.util.Queue;

public class FunctionalUnitSingleton {
	private static FunctionalUnitSingleton instance=null;
	/*
	 * Like global variable, the queue of unit will hold the number of divice as queue.
	 * if adder are of number 4 and piplined then the queue size will be 4
	 */
	private Queue<Instruction> fpAdder=new LinkedList<Instruction>();
	private Queue<Instruction> fpMultiplier=new LinkedList<Instruction>();
	private Queue<Instruction> fpDivider=new LinkedList<Instruction>();
	private Queue<Instruction> intUnit=new LinkedList<Instruction>();
	private Queue<Instruction> intUnit2=new LinkedList<Instruction>();
	private int fpAdderSize;
	private int fpMultiplierSize;
	private int fpDividerSize;


	private int intUnitSize;
	private int intUnit2Size;
	//private Queue<Instruction> fpMultiplier=new Queue[1];
	//private Queue<Instruction>[]fpDivider=new Queue[1];
	//private Queue<Instruction>[]intUnit=new Queue[1];
	/*
	 * required clock cycles
	 */
	private boolean isfpAdderPiplined=false,isfpMultiplierPiplined=false,isfpDividerPiplined=false,isintUnitPiplined=true,isinitUnit2Piplined=true;
	int fpAdderReqCycles=0,fpMultiplierReqCycles=0,fpDividerReqCycles=0,intUnitReqCycles=1,mainMemAccesstime=0,iCacheAccessTime=0,dCacheAccesstime=0,intUnit2ReqCycles=1;


	public int getFpAdderSize() {
		if(isfpAdderPiplined)
			return fpAdderReqCycles;
		else return 1;
	}
	public void setFpAdderSize(int fpAdderSize) {
		this.fpAdderSize = fpAdderSize;
	}
	public int getFpMultiplierSize() {
		if(isfpMultiplierPiplined)
			return fpMultiplierReqCycles;
		else return 1;
	}
	public void setFpMultiplierSize(int fpMultiplierSize) {
		this.fpMultiplierSize = fpMultiplierSize;
	}
	public int getFpDividerSize() {
		if(isfpDividerPiplined)
			return fpDividerReqCycles;
		else return 1;
	}
	public void setFpDividerSize(int fpDividerSize) {
		this.fpDividerSize = fpDividerSize;
	}
	public int getIntUnitSize() {
		if(isintUnitPiplined)
			return intUnitReqCycles;
		else return 1;
	}
	public void setIntUnitSize(int intUnitSize) {
		this.intUnitSize = intUnitSize;
	}
	public int getIntUnit2Size() {
		if(isinitUnit2Piplined)
			return intUnit2ReqCycles;
		else return 1;
	}
	public void setIntUnit2Size(int intUnit2Size) {
		this.intUnit2Size = intUnit2Size;
	}
	public Queue<Instruction> getIntUnit2() {
		return intUnit2;
	}
	public void setIntUnit2(Queue<Instruction> intUnit2) {
		this.intUnit2 = intUnit2;
	}
	public boolean isIsinitUnit2Piplined() {
		return isinitUnit2Piplined;
	}
	public void setIsinitUnit2Piplined(boolean isinitUnit2Piplined) {
		this.isinitUnit2Piplined = isinitUnit2Piplined;
	}
	public int getIntUnit2ReqCycles() {
		return intUnit2ReqCycles;
	}
	public void setIntUnit2ReqCycles(int intUnit2ReqCycles) {
		this.intUnit2ReqCycles = intUnit2ReqCycles;
	}
	public boolean isIsfpAdderPiplined() {
		return isfpAdderPiplined;
	}
	public void setIsfpAdderPiplined(boolean isfpAdderPiplined) {
		this.isfpAdderPiplined = isfpAdderPiplined;
	}
	public boolean isIsfpMultiplierPiplined() {
		return isfpMultiplierPiplined;
	}
	public void setIsfpMultiplierPiplined(boolean isfpMultiplierPiplined) {
		this.isfpMultiplierPiplined = isfpMultiplierPiplined;
	}
	public boolean isIsfpDividerPiplined() {
		return isfpDividerPiplined;
	}
	public void setIsfpDividerPiplined(boolean isfpDividerPiplined) {
		this.isfpDividerPiplined = isfpDividerPiplined;
	}
	public boolean isIsintUnitPiplined() {
		return isintUnitPiplined;
	}
	public void setIsintUnitPiplined(boolean isintUnitPiplined) {
		this.isintUnitPiplined = isintUnitPiplined;
	}



	public static FunctionalUnitSingleton getInstance(){
		if(instance==null){
			instance=new FunctionalUnitSingleton();
		}
		return instance;
	}
	/**
	 * @return the fpAdder
	 */
	public Queue<Instruction> getFpAdder() {

		return fpAdder;
	}

	/**
	 * @param fpAdder the fpAdder to set
	 */
	public void setFpAdder(Queue<Instruction> fpAdder) {
		this.fpAdder = fpAdder;
	}
	/**
	 * @param fpMultiplier the fpMultiplier to set
	 */
	public void setFpMultiplier(Queue<Instruction> fpMultiplier) {
		this.fpMultiplier = fpMultiplier;
	}
	/**
	 * @param fpDivider the fpDivider to set
	 */
	public void setFpDivider(Queue<Instruction> fpDivider) {
		this.fpDivider = fpDivider;
	}
	/**
	 * @param intUnit the intUnit to set
	 */
	public void setIntUnit(Queue<Instruction> intUnit) {
		this.intUnit = intUnit;
	}
	/**
	 * @return the fpMultiplier
	 */
	public Queue<Instruction> getFpMultiplier() {
		return fpMultiplier;
	}
	/**
	 * @param fpMultiplier the fpMultiplier to set
	 */
	/*public void setFpMultiplier(int requiredCycles,boolean piplined) {

	if(piplined)
		this.fpMultiplier=new Queue[requiredCycles];
	else
		this.fpMultiplier=new Queue[1];
}*/
	/**
	 * @return the fpDivider
	 */
	public Queue<Instruction> getFpDivider() {
		return fpDivider;
	}
	/**
	 * @param fpDivider the fpDivider to set
	 */
	/*public void setFpDivider(int requiredCycles,boolean piplined) {

	if(piplined)
		this.fpDivider=new Queue[requiredCycles];
	else
		this.fpDivider=new Queue[1];
}*/
	/**
	 * @return the intUnit
	 */
	public Queue<Instruction> getIntUnit() {
		return intUnit;
	}
	/**
	 * @param intUnit the intUnit to set
	 */
	/*public void setIntUnit(int requiredcycle,boolean piplined) {
	this.intUnit = intUnit;
	if(piplined)
		this.intUnit=new Queue[requiredcycle];
	else
		this.intUnit=new Queue[1];
}*/
	/**
	 * @return the fpAdderReqCycles
	 */
	public int getFpAdderReqCycles() {
		return fpAdderReqCycles;
	}
	/**
	 * @param fpAdderReqCycles the fpAdderReqCycles to set
	 */
	public void setFpAdderReqCycles(int fpAdderReqCycles) {
		this.fpAdderReqCycles = fpAdderReqCycles;
	}
	/**
	 * @return the fpMultiplierReqCycles
	 */
	public int getFpMultiplierReqCycles() {
		return fpMultiplierReqCycles;
	}
	/**
	 * @param fpMultiplierReqCycles the fpMultiplierReqCycles to set
	 */
	public void setFpMultiplierReqCycles(int fpMultiplierReqCycles) {
		this.fpMultiplierReqCycles = fpMultiplierReqCycles;
	}
	/**
	 * @return the fpDividerReqCycles
	 */
	public int getFpDividerReqCycles() {
		return fpDividerReqCycles;
	}
	/**
	 * @param fpDividerReqCycles the fpDividerReqCycles to set
	 */
	public void setFpDividerReqCycles(int fpDividerReqCycles) {
		this.fpDividerReqCycles = fpDividerReqCycles;
	}
	/**
	 * @return the fpintUnitReqCycles
	 */
	public int getintUnitReqCycles() {
		return intUnitReqCycles;
	}
	/**
	 * @param fpintUnitReqCycles the fpintUnitReqCycles to set
	 */
	public void setintUnitReqCycles(int intUnitReqCycles) {
		this.intUnitReqCycles = intUnitReqCycles;
	}
	/**
	 * @return the mainMemAccesstime
	 */
	public int getMainMemAccesstime() {
		return mainMemAccesstime;
	}
	/**
	 * @param mainMemAccesstime the mainMemAccesstime to set
	 */
	public void setMainMemAccesstime(int mainMemAccesstime) {
		this.mainMemAccesstime = mainMemAccesstime;
	}
	/**
	 * @return the iCacheAccessTime
	 */
	public int getiCacheAccessTime() {
		return iCacheAccessTime;
	}
	/**
	 * @param iCacheAccessTime the iCacheAccessTime to set
	 */
	public void setiCacheAccessTime(int iCacheAccessTime) {
		this.iCacheAccessTime = iCacheAccessTime;
	}
	/**
	 * @return the dCacheAccesstime
	 */
	public int getdCacheAccesstime() {
		return dCacheAccesstime;
	}
	/**
	 * @param dCacheAccesstime the dCacheAccesstime to set
	 */
	public void setdCacheAccesstime(int dCacheAccesstime) {
		this.dCacheAccesstime = dCacheAccesstime;
	}

}
